var list = new ArrayList();
var showTimes = 0;
var time = 0;
var indexType = "common"
var yyyy_MM_dd_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
var yyyyMMdd_PARSER = new SimpleDateFormat("yyyyMMdd");
var yyyy_MM_dd_HH_mm_ss_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

var v6_cmb_java_funcs = {
    openHomePage: function () {
        //先打开首页
        var ieStatus = luaFuncs.open();
        if (equals(ieStatus, "0")) {
            luaFuncs.open();
        }
        var indextHtml = get_html();
        show();
        //判断是否存在是扫码界面，如果是扫码界面，点击右上角的电脑标志，进入正常的页面
        storeDataToFile(context, indextHtml, "indextHtml.html");
        var doc = Jsoup.parse(indextHtml);
        if (doc != null && doc.select("#goQRCodeLogin") != null && indextHtml.contains("goQRCodeLogin")) {
            //扫码界面存在，点击进入到正常页面
            luaFuncs.call_showPassWordLogin();
            indexType = "special";
        }
        context.put("indextHtml", indextHtml);
    },
    /**
     * 检查代理是否可用
     * @return
     */
    checkProxyAvailable: function () {
        logger.info("任务taskKey = {}, 进入到检查登录是否有代理IP异常方法", context.get(LUA_TASK_KEY));
        var indextHtml = context.get("indextHtml");
        //判断是否代理异常的function
        var isCorrectFunc = function (indextHtml) {
            var doc = Jsoup.parse(indextHtml);
            return doc != null && doc.select("#UniLoginForm") != null
        }
        //获取异常信息的方法function
        var getErrorMsgFunc = function (indextHtml) {
            return "代理ip异常";
        }
        //返回信息
        return assertTrueOrThrowException(indextHtml, isCorrectFunc, getErrorMsgFunc)
    },
    /**
     * 检查网站是否可用
     * @returns {*}
     */
    checkTargetWebsiteAvailable: function () {
        logger.info("任务taskKey = {}, 进入检查招商银行网站是否可用方法", context.get(LUA_TASK_KEY));
        //暂时没有此步骤
        return true;
    },

    /**
     * 检查是否安装控件
     * @returns {boolean}
     */
    checkControlAvailable: function () {
        logger.info("任务:{},进入到检查是否安装控件或者控件升级方法", context.get(LUA_TASK_KEY));
        //调用lua脚本进行检测控件是否可用
        var checkResult = Boolean.valueOf(luaFuncs.checkControl())
        //用于获取控件检测结果的function
        var isCorrectFunc = function (checkResult) {
            return checkResult;
            //return false;
        }
        //用户获取控件检测错误信息的function
        var getErrorMsgFunc = function (checkResult) {
            return "控件检测失败，控件未安装或者控件升级";
        }
        return assertTrueOrThrowException(checkResult, isCorrectFunc, getErrorMsgFunc)
    },
    needRefreshHomePageOrNot: function () {
        return true;
    },
    needResetEnvironment: function () {
        getProxyInfo(context);
        //context.put("proxyAvailable",false);
        return true;
    },
    //登录阶段方法
    login: function () {
        // 输入基本信息

        inputBase()

        //输入图片验证码
        inputImg()
        //输入短信验证码
        inputSms()

        var index_html = get_html();
        storeDataToFile(context, index_html, "index_html.html");
        //获取登录后的页面
        var index_frame = luaFuncs.get_login_index_html();
        index_frame = commUtilFun.get_html_with_retry(index_frame, "大众版最近更新")
        storeDataToFile(context, index_frame, "index_frame_html.html");
        //LblTop
        var indexHaveRightMsgFun = function (index_frame) {
            return index_frame != null && index_frame.contains("大众版最近更新");
        }
        var indexErrorMsg = function () {
            return "登录超时"
        }
        assertTrueOrThrowException(index_frame, indexHaveRightMsgFun, indexErrorMsg)
    },

    //TODO:1、将交易记录的查询全部放到js中抓取解析  2、将所有的现场进行保存页面和截图  3、重构解析代码分离抓取和解析

    crawl: function () {
        //获取卡列表信息
        commUtilFun.get_card_list();
        //解析借记卡列表
        commUtilFun.parse_card_list_html();

        if (context.get(LUA_TASK_CARD_TYPE).equals("DEBITCARD")) {
            //借记卡信息抓取 -- 假设都是一张借记卡
            context.put(keys.DEBT_CARD_SIZE, context.get("cmb_debitCardSize"));
            createData();//构建表头
            var data_list = context.get(ALL_DATA);
            //循环多张卡
            for (var i = 0; i < data_list.size(); i++) {
                var creditCardAllData = data_list.get(i);
                //获取借记卡开户信息
                debit_commonFun.get_card_open_info_html();
                //解析开户信息 卡号 姓名 开户地
                debit_commonFun.parse_card_open_info_html(creditCardAllData);
                //获取借记卡余额信息，存款信息
                debit_commonFun.get_debit_balance_deposits();
                //解析存款信息
                debit_commonFun.parse_debit_balance_deposits(creditCardAllData);
                //获取账户交易明细，可以抓取13个月的账户交易明细,循环下面所有子账户，选中当前卡号的option
                debit_commonFun.get_debit_bill_index_html(context.get("cmb_card_num_four"));
                //解析获取一卡通账户下拉列表内容
                debit_commonFun.parse_debit_bill_index_html();
                //获取各个子账户
                debit_commonFun.parse_debit_sub_account_list();
                //循环子账户获取历史消费明细
                var sub_account_list = context.get("cmb_sub_account_list");
                for (var j = 0; j < sub_account_list.size(); j++) {
                    //获取该子账号下的历史消费明细
                    debit_commonFun.get_debit_sub_account_shopping_html(i,j);
                    //解析该子账户的历史交易明细
                    debit_commonFun.parse_debit_sub_account_shopping_html(creditCardAllData);
                }
            }
        } else if (context.get(LUA_TASK_CARD_TYPE).equals("CREDITCARD")) {
            var data_list = credit_commfuns.is_exsit_credit_card();
            //点击右上角信用卡按钮，进入到信用卡页面
            credit_commfuns.click_into_credit_index();
            //进入开卡页面获取option列表，拿到卡列表信息,将子账户信息和卡号信息对应放入map中备用
            for (var i = 0; i < context.get("cmb_creditCardSize"); i++) {
                var creditCardAllData = data_list.get(i);
                credit_commfuns.click_into_credit_open_index(i);
                //解析开卡信息获取各个卡片信息
                credit_commfuns.parse_credit_open_index();
                var open_flag = context.get("cmb_open_flag");
                if(open_flag == false){
                    //移除这个对象
                    data_list.remove(creditCardAllData);
                    i = i - 1;
                    continue;
                }
                if(data_list == null || data_list.size() <= 0){
                    logger.error("任务【{}】,未能获取到卡列表信息", context.get(LUA_TASK_KEY));
                    throw new BankException("BALO-20304-30", "未能获取到卡列表信息");
                }

                //跳转到信用卡主页，获取到信用卡的，额度，账单日，还款日信息
                credit_commfuns.click_into_credit_index_and_select_option(i);
                //解析信用卡首页信息
                credit_commfuns.parse_credit_card_index_html(i, creditCardAllData);
                //进入已出账单信息，选中对应option，返回页面
                credit_commfuns.click_into_done_bill_index_and_select_option(i);
                //解析已出账单信息，获取请求的参数信息
                credit_commfuns.parse_done_bill_list_html(i);
                //抓取解析已出账单数据
                var paramList = context.get("cmb_credit_done_param");
                for (var j = 0; j < paramList.size(); j++) {
                    var bill_mon = paramList.get(j).get("IN_YYYYMM");
                    //请求已出账单数据
                    credit_commfuns.get_credit_done_bill_html(i, paramList.get(j));
                    //解析已出账单数据
                    credit_commfuns.parse_credit_done_bill_html(creditCardAllData, bill_mon, j);
                }
                //抓取未出账单
                credit_commfuns.get_credit_undone_bill_html(i);
                //解析未出账单信息
                credit_commfuns.parse_credit_undone_bill_html(creditCardAllData,credit_commfuns.get_undone_bill_date());
            }
        }
    },
    exitLogin: function () {
    }
}

/**
 * 输入基本信息的方法
 * @returns {number}
 */
function inputBase() {
    logger.info("任务taskKey = {}, 显示窗口", context.get(LUA_TASK_KEY));
    showTimes = System.nanoTime();
    //打开窗口
    show();
    var cardNum = getLoginParams(context)[0];
    //lua根据id输入卡号
    var card = luaFuncs.input_username(cardNum);
    logger.info("{}, 输入账号返回的值:{}", context.get(LUA_TASK_KEY), card);
    //lua根据id输入登录密码
    var pwd = luaFuncs.input_password(context.get(LUA_TASK_TOKEN));
    logger.info("{}, 输入密码返回的值:{}", context.get(LUA_TASK_KEY), pwd);
    hide();
    //检查用户名密码是否正确输入
    var isCorrectFunc = function () {
        return Boolean.valueOf(card) && Boolean.valueOf(pwd)
    }
    //获取最终的错误信息
    var getErrorMsgFunc = function () {
        return "密码因控件输入错误";
    }
    return assertTrueOrThrowException("", isCorrectFunc, getErrorMsgFunc)
}

/**
 * 输入图片验证码的方法
 */
function inputImg() {
    logger.info("任务taskKey = {},进入输入图片验证码方法", context.get(LUA_TASK_KEY));
    var taskKey = context.get(LUA_TASK_KEY);
    showTimes = System.nanoTime() - showTimes;
    logger.info("任务taskKey = {}, 窗口显示时间：{}", taskKey, showTimes);
    logger.info("任务taskKey = {}, 点击登录按钮", taskKey);
    var result = luaFuncs.clickLoginButton(indexType);
    if (Boolean.valueOf(luaFuncs.zs_check_img())) {
        logger.info("任务taskKey = {}, 需要识别验证码", taskKey);
        result = isNeedImg();
    }
    storeDataToFile(context, result, "checkResult.html")
    //var imgCheckResult = checkResult(result);
    //校验登录是否成功function
    var isCorrectFunc = function (result) {
        if (result.equals("success")) {
            return true
        } else {
            return false
        }
    }
    //获取登录过程错误信息
    var getErrorMsgFunc = function (result) {
        if (result.contains("查询密码错误")) {
            return "登录失败：对不起，查询密码错误。";
        } else if (result.contains("账户未设查询密码")) {
            return "登录失败：对不起，账户未设查询密码。";
        } else if (result.contains("查询密码错误次数超限")) {
            return "登录失败：对不起，查询密码错误次数超限。";
        } else {
            return result.replace(/\([\s\S]*\)/g, "");
        }


    }
    logger.info("任务taskKey = {}, 点击登录结果：{}", taskKey, result);
    return assertTrueOrThrowException(result, isCorrectFunc, getErrorMsgFunc)
}

/**
 * 输入短信验证码的方法
 */
function inputSms() {
    // 检测是否需要短信验证码
    var needMessage = luaFuncs.checkMessage();
    logger.info("任务taskKey = {}, 检查是否需要短信验证码: {}", context.get(LUA_TASK_KEY), Boolean.valueOf(needMessage) ? "需要" : "不需要");
    // 校验短信输入结果，如果不需要短信返回true
    var resultMap = new LinkedHashMap();
    if (Boolean.valueOf(needMessage)) {
        //发送验证码
        var sendResult = Boolean.valueOf(luaFuncs.sendMessage());
        if (sendResult) {
            var smsCode = waitSmsCodeBySeconds(context, 240);
            logger.info("任务taskKey = {}, 短信验证码: {}", context.get(LUA_TASK_KEY), smsCode);
            if (!Boolean.valueOf(luaFuncs.receiveMessage(smsCode))) {
                resultMap.put("smsCheckResult", false);
            } else {
                resultMap.put("smsSendResult", true);
                resultMap.put("smsCheckResult", true);
            }
        } else {
            resultMap.put("smsSendResult", false);
        }
    } else {
        resultMap.put("smsSendResult", true);
        resultMap.put("smsCheckResult", true);
    }
    //校验短信发送以及校验结果
    var isCorrectFunc = function (resultMap) {
        //如果短信发失败或者短信校验失败都返回false，任务结束
        if (!resultMap.get("smsCheckResult") || !resultMap.get("smsSendResult")) {
            return false
        } else {
            return true
        }
    }
    // 获取短信输入错误描述
    var getErrorMsgFunc = function (resultMap) {
        if (resultMap.get("smsCheckResult")) {
            return "验证验证码失败，原因：请输入正确的验证码或重新申请验证码。ErrCode:02";
        } else if (resultMap.get("smsSendResult")) {
            return "短信验证码发送频繁，请稍后重试";
        }
        return "短信验证码错误"
    }
    return assertTrueOrThrowException(resultMap, isCorrectFunc, getErrorMsgFunc)

}

/**
 * 检查是否需要图片验证码
 * @return
 * @throws Exception
 */
function isNeedImg() {
    var taskKey = context.get(LUA_TASK_KEY);
    context.put(TASK_IMG_PATH, get_image_by_id("ImgExtraPwd"));
    // var imgCode = waitImgCodeBySeconds(context,60, true);
    context.put(TASK_IMG_REGEX, "[0-9]{4}");
    var imgCode = waitImgCodeBySecondsByJs(context, 60, true, 3);
    if (StringUtils.isBlank(imgCode) || imgCode.length() != 4) {
        logger.info("任务taskKey = {}, 验证码信息：打码位数不足四位，手动补足 {}", taskKey, imgCode);
        imgCode = waitImgCodeBySeconds(context, 60, true);
    }
    logger.info("任务taskKey = {}, 输入图片验证码，{}", taskKey, imgCode);
    var msg = set_input_text_by_id("ExtraPwd", imgCode.toLowerCase());
    logger.info("任务taskKey = {}, 图片验证码返回信息：{}", taskKey, msg);
    var result = luaFuncs.clickLoginButton(indexType);
    return result;
}


var currencyTypes = {
    "人民币": "CNY",
    "美元": "USD",
    "英镑": "GBP",
    "欧元": "EUR",
    "日元": "JPY",
    "港币": "HKD",
    "加拿大元": "CAD",
    "瑞士法郎": "CHF",
    "澳大利亚元": "AUD",
    "新加坡元": "SGD"
}

var chinese2Number = {
    "一": 1,
    "二": 2,
    "三": 3,
    "四": 4,
    "五": 5,
    "半": 6,
    "六": 6,
    "七": 7
}

var interestMappings = {
    "活期": 0.003,
    "通知存款": {
        "一天": 0.0055,
        "七天": 0.011
    },
    "存本取息": {
        "一年": 0.0135,
        "三年": 0.0155,
        "五年": 0.0155
    },
    "整存整取": {
        "三个月": 0.0135,
        "六个月": 0.0155,
        "一年": 0.0175,
        "二年": 0.0225,
        "三年": 0.0275,
        "五年": 0.0275
    },
    "零存整取": {
        "一年": 0.0135,
        "三年": 0.0155,
        "五年": 0.0155
    },
    "整存零取": {
        "一年": 0.0135,
        "三年": 0.0155,
        "五年": 0.0155
    }
}

var debit_commonFun = {
    /**
     * 获取借记卡开户信息
     */
    get_card_open_info_html: function () {
        logger.info("任务【{}】,招商银行开始获取一卡通开户信息", context.get(LUA_TASK_KEY));
        var html = luaFuncs.get_card_open_info();
        html = commUtilFun.get_html_with_retry(html, "一卡通开户信息");
        luaFuncs.saveHtmlAndImage("card_open_info");
        storeDataToFile(context, html, "card_open_info.html");
        context.put("cmb_card_open_info", html);
        logger.info("任务【{}】,招商银行获取一卡通开户信息完成", context.get(LUA_TASK_KEY));
    },

    /**
     * 解析一卡通开户信息
     */
    parse_card_open_info_html: function (creditCardAllData) {
        try {
            logger.info("任务【{}】,招商银行解析一卡通开户信息", context.get(LUA_TASK_KEY));
            var html = context.get("cmb_card_open_info");
            var doc = Jsoup.parse(html);
            //#dgSubAccRecSet > tbody > tr:nth-child(2)
            var tr = doc.select("#dgSubAccRecSet > tbody > tr:nth-child(2)")
            if (tr != null && tr.text().contains("账户查询")) {
                //获取卡号 用户名 开户地
                var full_card_num = doc.select("#SubAccountNo") != null ? doc.select("#SubAccountNo").attr("value") : doc.select("#dgSubAccRecSet > tbody > tr:nth-child(2) > td:nth-child(2)").text();
                creditCardAllData.setFullCardNum(full_card_num);
                var card_num = full_card_num.substring(full_card_num.length - 4, full_card_num.length);
                context.put("cmb_card_num_four", card_num);
                creditCardAllData.setCardNum(card_num);
                creditCardAllData.setNameOnCard(doc.select("#dgSubAccRecSet > tbody > tr:nth-child(2) > td:nth-child(3)").text());
                creditCardAllData.setOpenBank(doc.select("#dgSubAccRecSet > tbody > tr:nth-child(2) > td:nth-child(4)").text());
            } else {
                logger.error("任务【{}】,招商银行未能获取到一卡通开户信息", context.get(LUA_TASK_KEY))
            }
            logger.info("任务【{}】,招商银行解析一卡通开户信息完成", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,招商银行解析一卡通开户信息异常：【{}】", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    /**
     * 获取借记卡的存款信息页面
     */
    get_debit_balance_deposits: function () {
        logger.info("任务【{}】,招商银行获取一卡通存款信息", context.get(LUA_TASK_KEY));
        var html = luaFuncs.get_debit_balance_html();
        html = commUtilFun.get_html_with_retry(html, "定活互转");
        storeDataToFile(context, html, "debit_balance_html.html");
        luaFuncs.saveHtmlAndImage("debit_balance_html");
        context.put("cmb_debit_balance_html", html);
        logger.info("任务【{}】,招商银行获取一卡通存款信息完成", context.get(LUA_TASK_KEY));
    },

    /**
     * 解析借记卡余额存款信息
     */
    parse_debit_balance_deposits: function (creditCardAllData) {
        try {
            logger.info("任务【{}】,招商银行解析一卡通存款信息", context.get(LUA_TASK_KEY));
            var html = context.get("cmb_account_card_list");
            var doc = Jsoup.parse(html);
            var balance = doc.select("#uc_GeneAccInfoDC0_lblAmountConvertRMB").text().replace(",", "").replace(/\s+/g, "");
            logger.info("任务【{}】,解析获取到借记卡账户余额为【{}】", context.get(LUA_TASK_KEY), balance);
            creditCardAllData.setBalance(new BigDecimal(balance));
            creditCardAllData.setCreditLimit(null);
            creditCardAllData.setCashBalance(null);
            creditCardAllData.setCashLimit(null);

            //存款信息解析
            var html2 = context.get("cmb_debit_balance_html");
            var deposit_doc = Jsoup.parse(html2);
            var deposits = new ArrayList();
            //活期存款
            var table_huo = deposit_doc.select("#dgCurrentSubAccRecSet");
            if (table_huo != null) {
                //活期没有计息日，到期日，时间单位
                var trs_huo = table_huo.select("tr");
                if (trs_huo != null && trs_huo.size() > 1) {
                    for (var i = 1; i < trs_huo.size(); i++) {
                        logger.info("任务【{}】,招商银行借记卡，开始解析获取活期数据,第【{}】条", context.get(LUA_TASK_KEY), i);
                        var tds = trs_huo.get(i).select("td");
                        var deposit_huo = new CreditCardTimeDeposit();
                        deposit_huo.setBalance(new BigDecimal(tds.get(3).text().replace(/\s+/g, "").replace(",", "")));
                        deposit_huo.setDepositType("活期");
                        deposit_huo.setCurrencyType(currencyTypes[tds.get(2).text().replace(/\s+/g, "").replace(",", "")]);
                        deposit_huo.setInterest(new BigDecimal(interestMappings["活期"]).setScale(3,RoundingMode.HALF_UP));
                        deposit_huo.setPeriod(null);
                        deposits.add(deposit_huo);
                    }
                }
            }

            //整存整取
            var zczq_table = deposit_doc.select("#dgFixSubAccRecSet");
            if (zczq_table != null) {
                var trs = zczq_table.select("tr");
                if (trs != null && trs.size() > 1) {
                    for (var i = 0; i < trs.size(); i++) {
                        logger.info("任务【{}】,招商银行借记卡，开始解析获取整存整取数据,第【{}】条", context.get(LUA_TASK_KEY), i);
                        var tds = trs.get(i).select("td");
                        var deposit_zczq = new CreditCardTimeDeposit();
                        deposit_zczq.setBalance(new BigDecimal(tds.get(2).text().replace(",", "").replace(/\s+/g, "")));
                        deposit_zczq.setDepositType("整存整取");
                        var period = tds.get(6).text().replace(",", "").replace(/\s+/g, "");
                        deposit_zczq.setPeriod(chinese2Number[period.substring(0, 1)]);
                        deposit_zczq.setCurrencyType(currencyTypes[tds.get(1).text().replace(/\s+/g, "")]);
                        deposit_zczq.setPeriodUnit(period.substring(period.length - 1, period.length));
                        deposit_zczq.setInterest(new BigDecimal(interestMappings["整存整取"][period]));
                        deposit_zczq.setDepositDate(tds.get(5).text().replace(/\s+/g, ""));
                        deposit_zczq.setDueDate(tds.get(7).text().replace(/\s+/g, ""));
                        deposits.add(deposit_zczq);
                    }
                }
            }
            creditCardAllData.setDeposits(deposits);
            logger.info("任务【{}】,招商银行解析一卡通存款信息完成：【{}】", context.get(LUA_TASK_KEY), JSON.toJSONString(deposits));
        } catch (e) {
            logger.error("任务【{}】,招商银行解析一卡通存款信息异常：【{}】", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    /**
     * 获取借记卡消费明细
     */
    get_debit_bill_index_html: function (card_num) {
        logger.info("任务【{}】,招商银行借记卡，开始跳转到历史账单页面", context.get(LUA_TASK_KEY));
        var html = luaFuncs.get_debit_bill_index_html(card_num);
        html = commUtilFun.get_html_with_retry(html, "历史交易查询");
        storeDataToFile(context, html, "debit_bill_index.html");
        luaFuncs.saveHtmlAndImage("debit_bill_index");
        context.put("cmb_debit_bill_index_html", html);
        if (!html.contains("历史交易查询")) {
            throw new BankException("BALO-99601-50", "登录成功后页面跳转超时");
        }
        logger.info("任务【{}】,招商一卡通成功跳转到历史交易查询页面", context.get(LUA_TASK_KEY));

    },


    /**
     * 解析一卡通历史交易首页的信息，获取卡列表，最近交易时间
     */
    parse_debit_bill_index_html: function () {
        try {
            logger.info("任务【{}】，招商一卡通历史交易首页解析开始", context.get(LUA_TASK_KEY));
            var html = context.get("cmb_debit_bill_index_html");
            var doc = Jsoup.parse(html);
            var card_select_ele = doc.select("#ddlDebitCardList");
            var card_list_bill = new ArrayList();
            if (card_select_ele != null && card_select_ele.select("option") != null && card_select_ele.select("option").size() > 0) {
                var options = card_select_ele.select("option");
                for (var i = 0; i < options.size(); i++) {
                    card_list_bill.add(options.get(i).text().replace(/\s+/g, ""));
                }
            }
            context.put("cmb_card_list_bill", card_list_bill);
            logger.info("任务【{}】,招商银行获取到历史交易页面卡列表长度【{}】，内容【{}】", context.get(LUA_TASK_KEY), card_list_bill.size(), card_list_bill);
            //获取账单开始结束时间
            var start_date = commUtilFun.get_date_with_some_mon("yyyyMMdd", -13);
            var end_date = commUtilFun.get_date_with_some_mon("yyyyMMdd", 0)
            var endDateEle = doc.select("#EndDate");
            if (endDateEle != null && StringUtils.isNotBlank(endDateEle.attr("value"))) {
                end_date = endDateEle.attr("value").replace(/\s+/g, "");
            }
            context.put("cmb_bill_start_date", start_date);
            context.put("cmb_bill_end_date", end_date);
            logger.info("任务【{}】,招商银行获取到历史交易的开始时间【{}】，结束时间【{}】", context.get(LUA_TASK_KEY), start_date, end_date);

        } catch (e) {
            logger.info("任务【{}】，招商一卡通历史交易首页解析异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    /**
     * 获取一卡通历史交易页面的子账户列表
     */
    parse_debit_sub_account_list: function () {
        try {
            logger.info("任务【{}】，招商银行开始获取历史交易页面子账户列表", context.get(LUA_TASK_KEY));
            var html = context.get("cmb_debit_bill_index_html");
            var doc = Jsoup.parse(html);
            //获取子账户列表 ddlSubAccountList
            var sub_account_list_ele = doc.select("#ddlSubAccountList");
            var sub_account_list = new ArrayList();
            if (sub_account_list_ele != null && sub_account_list_ele.select("option") != null && sub_account_list_ele.select("option").size() > 0) {
                var options = sub_account_list_ele.select("option");
                for (var i = 0; i < options.size(); i++) {
                    sub_account_list.add(options.get(i).text().replace(/\s+/g, ""));
                }
            }
            context.put("cmb_sub_account_list", sub_account_list);
            logger.info("任务【{}】,招商一卡通获取历史交易明细的子账户列表【{}】", context.get(LUA_TASK_KEY), sub_account_list);
        } catch (e) {
            logger.info("任务【{}】，招商一卡通历史交易首页解析异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    /**
     * 获取借记卡该子账户下的消费明细
     */
    get_debit_sub_account_shopping_html: function (i,index) {
        logger.info("任务【{}】，招商借记卡开始获取子账户【{}】的历史交易记录", context.get(LUA_TASK_KEY), index);
        var start_date = context.get("cmb_bill_start_date");
        var end_date = context.get("cmb_bill_end_date");
        var html = luaFuncs.get_debit_sub_account_shopping_html(start_date, end_date, index);
        Thread.sleep(2000);
        html = commUtilFun.get_html_with_retry(html, "历史交易记录");
        storeDataToFile(context, html, "debit_shopping_sheets" +i+"_"+ index + ".html");
        luaFuncs.saveHtmlAndImage("debit_shopping_sheets" + index);
        context.put("cmb_debit_bill_shopping_sheets", html);
        logger.info("任务【{}】，招商借记卡开始获取子账户【{}】的历史交易记录完成", context.get(LUA_TASK_KEY), index);
    },

    /**
     * 解析历史账单页
     * @param creditCardAllData
     */
    parse_debit_sub_account_shopping_html: function (creditCardAllData) {
        try {
            logger.info("任务【{}】,招商借记卡开始解析历史账单页", context.get(LUA_TASK_KEY));
            //创建13月的账单日期列表
            var html = context.get("cmb_debit_bill_shopping_sheets");
            var doc = Jsoup.parse(html);
            var end_date = commUtilFun.deal_str_date(doc.select("#BeginDate").attr("value").replace(/\s+/g, ""));
            var start_date = commUtilFun.deal_str_date(doc.select("#EndDate").attr("value").replace(/\s+/g, ""));
            if(StringUtils.isBlank(end_date) || StringUtils.isBlank(start_date)){
                logger.info("任务【{}】,开始日期【{}】,结束日期【{}】为空", context.get(LUA_TASK_KEY), start_date,end_date);
                return;
            }
            logger.info("任务【{}】,开始日期【{}】", context.get(LUA_TASK_KEY), start_date);
            var start_mon = start_date.substring(0, 7)
            //var end_date = last_tds.get(0).text().replace(/\s+/g, "");
            logger.info("任务【{}】,结束日期【{}】", context.get(LUA_TASK_KEY), end_date);
            var end_mon = end_date.substring(0, 7)
            var mon_list = commUtilFun.get_mon_list(start_mon, end_mon);
            var table = doc.select("#dgHistoryTransRecSet");
            if (table != null && table.select("tr") != null) {
                var trs = table.select("tr");
                if (trs.size() > 1) {
                    logger.info("任务【{}】,招商借记卡账单有内容", context.get(LUA_TASK_KEY));
                    var first_tds = trs.get(1).select("td");
                    var last_tds = trs.get(trs.size() - 1).select("td");
                    for (var i = 0; i < mon_list.size(); i++) {
                        var bill_mon = mon_list.get(i);
                        logger.info("任务【{}】，招商借记卡开始获取【{}】月账单信息", context.get(LUA_TASK_KEY), bill_mon);
                        //判断账单中是否有之前的改月账单，如果有，直接用之前的，如果没有就新拿一个
                        var billAllData = commUtilFun.is_exist_bill_with_mon(creditCardAllData, bill_mon);
                        //处理billAllData
                        commUtilFun.deal_debit_card_bill_all_data(billAllData, bill_mon);

                        //获取最大的orderIndex
                        commUtilFun.get_bigest_order_index(billAllData);
                        var shopping_order_index = context.get("shopping_order");
                        var shopping_sheets = new ArrayList();
                        for (var j = 1; j < trs.size(); j++) {
                            var tr = trs.get(j);
                            if (tr != null && tr.select("td") != null && tr.select("td").size() >= 7) {
                                //判断月份是否是该月的账单
                                var tds = tr.select("td");
                                if (bill_mon.equals((tds.get(0).text().replace(/\s+/g, "")).substring(0, 7))) {
                                    var desc = tds.get(5).text();

                                    var expense = new Expense();
                                    expense.setId(UUID.randomUUID().toString());
                                    expense.setCardNum(context.get("cmb_card_num_four"));
                                    expense.setOrderIndex(shopping_order_index++);

                                    var post_date = tds.get(0).text().replace(/\s+/g, "");
                                    var post_time = tds.get(1).text().replace(/\s+/g, "");

                                    if (equals(post_time, "")) {
                                        expense.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(post_date + " 00:00:00"));
                                    } else {
                                        expense.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(post_date + " " + post_time));
                                    }
                                    expense.setPostDate(yyyy_MM_dd_PARSER.parse(post_date));
                                    expense.setCurrencyType("CNY");
                                    var amount_money = StringUtils.isBlank(tds.get(2).text().replace(/\s+/g, "")) ? new BigDecimal("-" + tds.get(3).text().replace(/\s+/g, "").replace(",", "")) : new BigDecimal(tds.get(2).text().replace(/\s+/g, "").replace(",", ""));

                                    expense.setAmountMoney(amount_money);
                                    expense.setBalance(new BigDecimal(tds.get(4).text().replace(/\s+/g, "").replace(",", "")));
                                    expense.setCategory(classify(desc,expense.getAmountMoney()));
                                    expense.setTransAddr("");
                                    expense.setTransMethod("");
                                    expense.setTransChannel("");
                                    expense.setDescription(tds.get(5).text());
                                    expense.setRemark(tds.get(6).text());
                                    expense.setOppositeCardNo("");
                                    expense.setNameOnOppositeCard("");
                                    expense.setOppositeBank("");
                                    shopping_sheets.add(expense);
                                }
                            }
                        }
                        billAllData.setShoppingSheets(shopping_sheets);
                        billAllData.setInstallments(new ArrayList());
                    }
                }
            }

        } catch (e) {
            logger.info("任务【{}】，招商借记卡解析历史账单页解析异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },
}

/**
 * 信用卡方法集合
 */
var credit_commfuns = {
    //判断是否存在信用卡，如果没有抛出未获取到卡列表信息，存在返回构建的表头
    is_exsit_credit_card: function () {
        logger.info("任务【{}】,开始进行信用卡抓取", context.get(LUA_TASK_KEY));
        var card_size = context.get("cmb_creditCardSize");
        if (card_size <= 0) {
            logger.info("任务【{}】,未获取到卡片信息", context.get(LUA_TASK_KEY));
            throw new BankException("BALO-20304-30", "未获取到卡片信息");
        } else {
            logger.info("任务【{}】，获取到【{}】张信用卡信息", context.get(LUA_TASK_KEY), card_size);
            context.put(keys.CRED_CARD_SIZE, card_size);
            createData();//构建表头
            var data_list = context.get(ALL_DATA);
            return data_list;
        }
    },

    //进入到信用卡页面
    click_into_credit_index: function () {
        logger.info("任务【{}】,开始点击信用卡按钮进入到招商信用卡首页", context.get(LUA_TASK_KEY));
        var html = luaFuncs.click_into_credit_index();
        html = commUtilFun.get_html_with_retry(html, "已出账单查询");
        storeDataToFile(context, html, "credit_card_index.html");
        luaFuncs.saveHtmlAndImage("credit_card_index");
        if (!html.contains("已出账单查询")) {
            logger.info("任务【{}】,未能成功进入到信用卡页面", context.get(LUA_TASK_KEY));
            throw new BankException("BALO-20304-30", "未获取到卡片信息");
        }
        logger.info("任务【{}】,点击信用卡按钮成功进入到招商信用卡首页", context.get(LUA_TASK_KEY));
    },

    //进入到开卡信息页面,并解析获取到卡片信息
    click_into_credit_open_index: function (index) {
        logger.info("任务【{}】,招商信用卡开始进入到【{}】开卡信息页面，获取卡片信息", context.get(LUA_TASK_KEY), index);
        var html = luaFuncs.click_into_credit_open_index(index);
        html = commUtilFun.get_html_with_retry(html, "信用卡开卡");
        storeDataToFile(context, html, "credit_card_open_index"+index+".html");
        luaFuncs.saveHtmlAndImage("credit_card_open_index");
        context.put("cmb_credit_card_open_index_html", html);
        logger.info("任务【{}】,招商信用卡开始进入到【{}】完成，获取卡片信息", context.get(LUA_TASK_KEY), index);
    },

    //解析开卡信息，获取卡片信息,判断是否开卡，未开卡的删除这个creditData
    parse_credit_open_index: function () {
        try {
            logger.info("任务【{}】，招商银行信用卡开始解析卡片信息获取卡号，持卡人", context.get(LUA_TASK_KEY));
            var html = context.get("cmb_credit_card_open_index_html");
            var doc = Jsoup.parse(html);
            //#dgReckoningSet > tbody > tr:nth-child(2) > td:nth-child(5)
            var openele = doc.select("#dgReckoningSet > tbody > tr:nth-child(2) > td:nth-child(5)").text();
            if(openele == null || openele.contains("未开卡")){
                context.put("cmb_open_flag",false);
            }else{
                context.put("cmb_open_flag",true);
            }
            //获取到卡号以及持卡人
            var dgReckoningSet = doc.select("#dgReckoningSet");
            if (dgReckoningSet != null && dgReckoningSet.select("tr") != null && dgReckoningSet.select("tr").size() > 1) {
                var trs = dgReckoningSet.select("tr");
                for (var i = 1; i < trs.size(); i++) {
                    var tr = trs.get(i);
                    var tds = tr.select("td");
                    context.put("cmb_credit_card_no", tds.get(0).text().replace(/\s+/g, ""));
                    context.put("cmb_credit_name_on_card", tds.get(3).text().replace(/\s+/g, ""));
                    if (StringUtils.isNotBlank(tds.get(2).text().replace(/\s+/g, ""))) {
                        //存在电子卡情况，有卡类别的一般都是主卡
                        context.put("cmb_credit_card_no", tds.get(0).text().replace(/\s+/g, ""));
                        context.put("cmb_credit_name_on_card", tds.get(3).text().replace(/\s+/g, ""));
                        break;
                    }
                }
            }
            logger.info("任务【{}】，招商信用卡获取到卡号【{}】，持卡人信息【{}】", context.get(LUA_TASK_KEY), context.get("cmb_credit_card_no"), context.get("cmb_credit_name_on_card"));
        } catch (e) {
            logger.info("任务【{}】，招商银行信用卡开始解析卡片信息,异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //跳转到信用卡首页，并选中option，然后返回页面
    click_into_credit_index_and_select_option: function (index) {
        logger.info("任务【{}】，开始进入到信用卡首页，并选中对应的opotion", context.get(LUA_TASK_KEY));
        var html = luaFuncs.click_into_credit_index_and_select_option(index);
        html = commUtilFun.get_html_with_retry(html, "已出账单查询");
        storeDataToFile(context, html, "credit_index_" + index + ".html");
        luaFuncs.saveHtmlAndImage("credit_index_" + index);
        context.put("cmb_credit_card_index_html", html);
        logger.info("任务【{}】，信用卡【{}】，获取信用卡首页成功", context.get(LUA_TASK_KEY), index);
    },

    //解析信用卡首页信息
    parse_credit_card_index_html: function (index, creditCardAllData) {
        try {
            logger.info("任务【{}】，开始解析信用卡首页信息，卡【{}】", context.get(LUA_TASK_KEY), index);
            var html = context.get("cmb_credit_card_index_html");
            var doc = Jsoup.parse(html);
            // 可以获取到，信用卡额度，信用卡现金额度，信用卡可用额度，账单日，还款日，对应美元
            var full_card_num = context.get("cmb_credit_card_no");
            var card_num = full_card_num.substring(full_card_num.length - 4, full_card_num.length);
            context.put("credit_card_num_4", card_num);
            var name_on_card = context.get("cmb_credit_name_on_card");
            var balance = doc.select("#RMBKYED") == null ? null : new BigDecimal(doc.select("#RMBKYED").text().replace(/\s+/g, "").replace(",", "").replace("￥", ""));
            logger.info("任务【{}】,抓取到的可用额度信息【{}】", context.get(LUA_TASK_KEY), balance);
            var cash_balance = doc.select("#RMBYJXJ") == null ? null : new BigDecimal(doc.select("#RMBYJXJ").text().replace(/\s+/g, "").replace(",", "").replace("￥", ""));
            logger.info("任务【{}】,抓取到的现金额度【{}】", context.get(LUA_TASK_KEY), cash_balance);
            var credit_limit = doc.select("#RMBXYED") == null ? null : new BigDecimal(doc.select("#RMBXYED").text().replace(/\s+/g, "").replace(",", "").replace("￥", ""));
            logger.info("任务【{}】,抓取到信用额度【{}】", context.get(LUA_TASK_KEY), credit_limit);
            var bill_day = doc.select("#MYZD") == null ? null : doc.select("#MYZD").text().replace(/\s+/g, "").replace("日", "")
            logger.info("任务【{}】,抓取到的账单日【{}】", context.get(LUA_TASK_KEY), bill_day);
            var payment_day = doc.select("#DQHQ") == null ? null : doc.select("#DQHQ").text().replace(/\s+/g, "").substring(8, 10);
            logger.info("任务【{}】,抓取到的还款日【{}】", context.get(LUA_TASK_KEY), payment_day);
            context.put("cmb_bill_day", bill_day);
            context.put("cmb_pay_due_day", payment_day);

            //设置creditCardAllData
            creditCardAllData.setFullCardNum(full_card_num);
            creditCardAllData.setCardNum(card_num);
            creditCardAllData.setNameOnCard(name_on_card);
            creditCardAllData.setBalance(balance);
            creditCardAllData.setCashBalance(cash_balance);
            creditCardAllData.setCashLimit(null);
            creditCardAllData.setCreditLimit(credit_limit);
            creditCardAllData.setOpenBank("");

            logger.info("任务【{}】,信用卡首页信息解析完成，未发现异常", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.info("任务【{}】，解析信用卡首页信息，卡【{}】,异常：{}", context.get(LUA_TASK_KEY), index, e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //跳转到信用卡已出账单页面，选中对应的option
    click_into_done_bill_index_and_select_option: function (index) {
        logger.info("任务【{}】，信用卡开始获取已出账单列表页，卡【{}】", context.get(LUA_TASK_KEY), index);
        var html = luaFuncs.click_into_done_bill_index_and_select_option(index);
        html = commUtilFun.get_html_with_retry(html, "已出账单查询");
        var client_no = "";
        for (var i = 0; i < 3; i++) {
            if (Jsoup.parse(html).select("#ClientNo") != null) {
                //可以成功获取到clientno
                client_no = Jsoup.parse(html).select("#ClientNo").attr("value");
                context.put("cmb_done_bill_client_no", client_no);
                logger.info("任务【{}】，成功获取到clientNo【{}】", context.get(LUA_TASK_KEY), client_no);
                break;
            } else {
                Thread.sleep(3000);
                html = luaFuncs.click_into_done_bill_index_and_select_option(index);
            }
        }
        if (StringUtils.isBlank(client_no)) {
            logger.info("任务【{}】,未能成功获取到clientNo", context.get(LUA_TASK_KEY));
        }
        storeDataToFile(context, html, "credit_done_bill_list_" + index + ".html");
        luaFuncs.saveHtmlAndImage("credit_done_bill_list_" + index);
        context.put("cmb_credit_done_bill_list_html", html);
        logger.info("任务【{}】,信用卡获取已出账单列表成功，卡【{}】", context.get(LUA_TASK_KEY), index);
    },

    //解析信用卡列表页
    parse_done_bill_list_html: function (index) {
        try {
            logger.info("任务【{}】，开始解析信用卡首页信息，卡【{}】", context.get(LUA_TASK_KEY), index);
            var html = context.get("cmb_credit_done_bill_list_html");
            var doc = Jsoup.parse(html);
            //获取其他三个请求参数
            var trs = doc.select("#dgReckoningInfo1").select("tr");
            var paramList = new ArrayList();
            for (var i = 1; i < trs.size(); i++) {
                var triggerFunc = trs.get(i).select("td:nth-child(6) > a:nth-child(1)").attr("onclick");
                if (StringUtils.isBlank(triggerFunc)) {
                    logger.error("任务【{}】，未获取到请求账单参数", context.get(LUA_TASK_KEY));
                    continue;
                }
                triggerFunc = getGroupByIndex("\\((.*?)\\)", triggerFunc, 1);
                triggerFunc = triggerFunc.replaceAll("'", "");
                var urls = triggerFunc.split(",");
                var paramMap = new LinkedHashMap();
                paramMap.put("ClientNo", context.get("cmb_done_bill_client_no"));
                paramMap.put("O_STMT_FLAG", urls[3].replaceAll("O_STMT_FLAG=", ""));
                paramMap.put("IN_YYYYMM", urls[4].replaceAll("IN_YYYYMM=", ""));
                paramMap.put("CreditAccNo", urls[5].replaceAll("CreditAccNo=", ""));
                paramList.add(paramMap);
            }
            context.put("cmb_credit_done_param", paramList);

            //构造请求头
            var referer1 = "https://pbsz.ebank.cmbchina.com/CmbBank_CreditCard_Loan/UI/CreditCard/LOAN/AM_QUERYRECKONINGSURVEYNEW.ASPX";
            var header = new LinkedHashMap();
            header.put("Accept", "text/html, application/xhtml+xml, */*");
            header.put("Accept-Encoding", "gzip, deflate");
            header.put("Accept-Language", "zh-CN");
            header.put("Cache-Control", "no-cache");
            header.put("Connection", "Keep-Alive");
            header.put("Content-Type", "application/x-www-form-urlencoded");
            header.put("Host", "pbsz.ebank.cmbchina.com");
            header.put("Referer", referer1);
            header.put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
            context.put("cmb_credit_done_header", header);

            //设置cookie信息
            var cookie = luaFuncs.getCookie();
            cookie = cookie.replaceAll("ProVersion=;", "");
            logger.info("任务taskKey{},获得的cookie为:{}", context.get(LUA_TASK_KEY), cookie);
            var splitCookie = cookie.split(";");
            for (var i = 0; i < splitCookie.length; i++) {
                logger.info("任务taskKey{},i={},分割后的cookie:{}", context.get(LUA_TASK_KEY), i, splitCookie[i]);
            }
            var wtfpc = splitCookie[3];//WTFPC=id=2baea506122084ca4091513912682600:lv=1513912682600:ss=1513912682600;
            var equelsFirst = wtfpc.indexOf("=");
            var newWtfpc = wtfpc.substring(equelsFirst + 1, wtfpc.length());
            logger.info("{}，分割后的WTFPC:{}", context.get(LUA_TASK_KEY), newWtfpc);
            var clientStamp = splitCookie[4];//ClientStamp=5705884305680781991
            logger.info("{},分割后的clientStamp:{}", context.get(LUA_TASK_KEY), clientStamp);
            RequestUtil.addCookie("WEBTRENDS_ID", "106.38.54.130-4146216912.30636578::02576353E233C56AB84FB601952B", "", null, "");
            RequestUtil.addCookie("TS01a34556", "01b3b6a2b3adb1bed2d772e05db5683a5686c1998ae3fd9bf0f65e9a7f7702f24f784830a4e234bd697af23450149c5d781b7e1cdb", "", null, "");
            RequestUtil.addCookie("WTFPC", newWtfpc, "", null, "");
            RequestUtil.addCookie("AuthType", "A", "", null, "/");
            RequestUtil.addCookie("DeviceType", "A", "", null, "/");
            RequestUtil.addCookie("ProVersion", "", "", null, "/");
            RequestUtil.addCookie("ClientStamp", clientStamp.split("=")[1], "", null, "");

            logger.info("任务【{}】，构造已出账单请求参数完成，卡【{}】", context.get(LUA_TASK_KEY), index);
        } catch (e) {
            logger.info("任务【{}】，解析信用卡首页信息，卡【{}】,异常：{}", context.get(LUA_TASK_KEY), index, e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //抓取已出账单
    get_credit_done_bill_html: function (index, paramMap) {
        logger.info("任务【{}】,开始获取信用卡已出账单信息，卡【{}】，账单月【{}】", context.get(LUA_TASK_KEY), index, paramMap.get("IN_YYYYMM"));
        Thread.sleep(1000);
        var header = context.get("cmb_credit_done_header");
        var url = "https://pbsz.ebank.cmbchina.com/CmbBank_CreditCard_Loan/UI/CreditCard/Loan/am_QueryReckoningListNew.aspx";
        var html = RequestUtil.post(url, paramMap, header);
        storeDataToFile(context, html, "credit_done_bill_html_" + index + "_" + paramMap.get("IN_YYYYMM") + ".html");
        context.put("cmb_credit_done_bill_html", html);
        logger.info("任务【{}】,获取信用卡已出账单信息，卡【{}】，账单月【{}】完成", context.get(LUA_TASK_KEY), index, paramMap.get("IN_YYYYMM"));
    },

    //解析已出账单信息
    parse_credit_done_bill_html: function (creditCardAllData, bill_mon, j) {
        try {
            logger.info("任务【{}】，开始解析信用卡【{}】月已出账单", context.get(LUA_TASK_KEY), bill_mon);
            bill_mon = bill_mon.substring(0, 4) + "-" + bill_mon.substring(4, 6);
            var html = context.get("cmb_credit_done_bill_html");
            if (html.contains("您当月未出账单") || html.contains("对不起，您的上次请求还未返回，请不要频繁操作") || html.contains("账单数据正在更新中，建议您在14 ：00以后登录网银查询，感谢您的配合！")) {
                logger.info("任务【{}】，信用卡已出账单，月份【{}】，没有账单信息，跳出继续", context.get(LUA_TASK_KEY), bill_mon);
                return;
            }
            var doc = Jsoup.parse(html);
            //获取一个可用的billAllData,分期，消费明细
            var billAllData = getDoneBillAllDataHeaderData(creditCardAllData);
            var installments = new ArrayList();
            var shopping_sheets = new ArrayList();

            //账单月
            billAllData.setBillMonth(bill_mon);
            //账单日
            var zdr = "";
            var zdzq_ele = doc.select("#fixBand6 > table > tbody > tr > td > table > tbody > tr > td:nth-child(3) > div > font");
            try {
                zdr = zdzq_ele.text().replace(/\s+/g, "").split("-")[1].replaceAll("/", "-");
            } catch (e) {
                logger.info("任务【{}】，解析账单日出现异常：{}", context.get(LUA_TASK_KEY), e);
                zdr = bill_mon + "-" + context.get("cmb_bill_day");
            }
            billAllData.setBillDate(yyyy_MM_dd_FORMAT.parse(zdr))
            //还款日
            var hkr = "";
            var hkr_ele = doc.select("#fixBand8 > table > tbody > tr > td > table > tbody > tr > td:nth-child(3) > div > font");
            try {
                hkr = hkr_ele.text().replace(/\s+/g, "").replaceAll("/", "-");
            } catch (e) {
                logger.info("任务【{}】，解析还款日出现异常：{}", context.get(LUA_TASK_KEY), e);
                hkr = bill_mon + "-" + context.get("cmb_pay_due_day");
            }
            billAllData.setPaymentDueDate(yyyy_MM_dd_FORMAT.parse(hkr));
            //本期账单金额
            var bqzdje_ele = doc.select("#fixBand18 > table > tbody > tr > td > table > tbody > tr > td:nth-child(3) > div > font");
            var bqzdje = new BigDecimal(bqzdje_ele == null ? null : commUtilFun.parse_money(bqzdje_ele.text()))
            if (j == 0) {
                context.put("cmb_credit_un_last_balance", bqzdje_ele == null ? null : commUtilFun.parse_money(bqzdje_ele.text()))
                context.put("cmb_last_bill_date", zdr);
            }
            billAllData.setNewBalance(bqzdje);
            billAllData.setUsdNewBalance(null);
            //最低还款额
            var zdhke_ele = doc.select("#fixBand18 > table > tbody > tr > td > table > tbody > tr > td:nth-child(5) > div > font");
            var zdhke = new BigDecimal(zdhke_ele == null ? null : commUtilFun.parse_money(zdhke_ele.text()));
            billAllData.setMinPayment(zdhke);
            billAllData.setUsdMinPayment(null);
            //上期账单金额
            var sqzdje_ele = doc.select("#fixBand13 > table > tbody > tr > td > table > tbody > tr > td:nth-child(3) > div > font");
            var sqzdje = new BigDecimal(sqzdje_ele == null ? null : commUtilFun.parse_money(sqzdje_ele.text()));
            billAllData.setLastBalance(sqzdje);
            billAllData.setUsdLastBalance(null);
            //上期还款金额
            var sqhkje_ele = doc.select("#fixBand13 > table > tbody > tr > td > table > tbody > tr > td:nth-child(4) > div > font");
            var sqhkje = new BigDecimal("-"+(sqhkje_ele == null ? null : commUtilFun.parse_money(sqhkje_ele.text())));
            billAllData.setLastPayment(sqhkje);
            billAllData.setUsdLastPayment(null);
            //本期新增款额
            var bqxzke_ele = doc.select("#fixBand13 > table > tbody > tr > td > table > tbody > tr > td:nth-child(5) > div > font");
            var bqxzke = new BigDecimal(bqxzke_ele == null ? null : commUtilFun.parse_money(bqxzke_ele.text()));
            billAllData.setNewCharges(bqxzke);
            billAllData.setUsdNewCharges(null);
            //循环利息
            var xhls_ele = doc.select("#fixBand13 > table > tbody > tr > td > table > tbody > tr > td:nth-child(7) > div > font");
            var xhls = new BigDecimal(xhls_ele == null ? null : commUtilFun.parse_money(xhls_ele.text()));
            billAllData.setInterest(xhls);
            billAllData.setUsdInterest(null);
            //信用卡额度
            var xyked_ele = doc.select("#fixBand6 > table > tbody > tr > td > table > tbody > tr > td:nth-child(5) > div > font");
            var xyked = new BigDecimal(xyked_ele == null ? null : commUtilFun.parse_money(xyked_ele.text()));
            billAllData.setCreditLimit(xyked);
            billAllData.setUsdCreditLimit(null);
            //预借现金额度
            billAllData.setCashLimit(null);
            billAllData.setUsdCashLimit(null);

            //开始解析购物明细
            var e = doc.select("#fixBand15");
            var index = 1;
            var year = bill_mon.substring(0, 4);
            for (var i = 0; i < e.size(); i++) {
                var element = e.get(i).select("table > tbody > tr > td > table > tbody > tr");
                if (element.select("td").size() < 7) {
                    continue;
                }
                var expense = new Expense();
                var tranDate = element.select("td").get(1).text().replace(/\s+/g, "");// 交易日期（yyyymmdd）
                if (StringUtils.isNotBlank(tranDate)) {
                    var sb = new StringBuilder(year + tranDate);
                    sb.insert(4, "-");
                    sb.insert(7, "-");
                    tranDate = sb.toString();
                } else {
                    tranDate = "";
                }
                var recordDate = element.select("td").get(2).text().replace(/\s+/g, "");// 记账日期（yyyymmdd）
                recordDate = year + recordDate;
                var sb = new StringBuilder(recordDate);
                sb.insert(4, "-");
                sb.insert(7, "-");
                recordDate = sb.toString();
                var transRemark = element.select("td").get(3).text().replace(/\s+/g, "");// 交易摘要

                var jyje = element.select("td").get(element.select("td").size() - 4).text().replace(/\s+/g, "");// 交易金额
                jyje = commUtilFun.parse_money(jyje);
                var cardNo = element.select("td").get(element.select("td").size() - 3).text().replace(/\s+/g, "");// 卡号末4位,如果不满足4位以*号补齐
                var transPlace = element.select("td").get(element.select("td").size() - 2).text().replace(/\s+/g, "");// 交易地点
                if (StringUtils.isBlank(transPlace)) {
                    transPlace = "";
                }
                expense.setId(UUID.randomUUID().toString());
                if (equals(tranDate, "")) {
                    expense.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(recordDate + " 00:00:00"));
                } else {
                    expense.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(tranDate + " 00:00:00"));
                }
                expense.setPostDate(yyyy_MM_dd_PARSER.parse(recordDate));
                // logger.info("打印摘要描述"+transRemark);
                expense.setDescription(transRemark.replaceAll("&nbsp;", " ").replaceAll(" ", " "));
                expense.setOrderIndex(index++);
                expense.setCurrencyType("CNY");
                expense.setBalance(null);
                expense.setAmountMoney(new BigDecimal(jyje));
                expense.setCardNum(cardNo);
                expense.setTransAddr(transPlace.replaceAll("&nbsp;", " ").replaceAll(" ", " "));
                expense.setCategory(classify(transRemark,expense.getAmountMoney()));
                expense.setTransMethod("");
                expense.setTransChannel("");
                expense.setRemark("");
                expense.setOppositeCardNo("");
                expense.setNameOnOppositeCard("");
                expense.setOppositeBank("");
                shopping_sheets.add(expense);
            }

            billAllData.setShoppingSheets(shopping_sheets);
            logger.info("任务【{}】,已出账单【{}】月份，消费明细数据获取完成：{}", context.get(LUA_TASK_KEY), bill_mon, JSON.toJSONString(shopping_sheets));

            //循环消费明细，设置分期数据
            var installment = new Installment();
            var installnum = 0;
            for (var i = 0; i < shopping_sheets.size(); i++) {
                var expense = shopping_sheets.get(i);
                var lists = getMatch("(账单分期)\\s*(.*?)\\s*(\\d{1,3}-\\d{1,3})", expense.getDescription());

                if (lists.size() == 1 && lists.get(0).size() == 3) {
                    var type = lists.get(0).get(1);
                    var installment_type = installmentTypeChange(type);
                    var dates = lists.get(0).get(2).split("-");
                    var total_month = Integer.parseInt(dates[1]);
                    var current_month = Integer.parseInt(dates[0]);
                    if (!expense.getDescription().contains("手续费")) {
                        installment.setAmountMoney(expense.getAmountMoney());
                        installment.setInstallmentDesc(expense.getDescription());
                    } else {
                        installment.setHandingFee(expense.getAmountMoney());
                        installment.setHandingfeeDesc(expense.getDescription());
                    }
                    installment.setCurrencyType("CNY");
                    installment.setTotalMonth(total_month);
                    installment.setCurrentMonth(current_month);
                    installment.setInstallmentType(installment_type);
                    installment.setTransferFee(null);
                    installment.setShoppingsheetId(UUID.randomUUID().toString());
                    installment.setPostDate(expense.getPostDate());
                    //根据记账时间计算出交易时间，并修改这个交易时间
                    var post_date_str = yyyy_MM_dd_FORMAT.format(expense.getPostDate())
                    var ins_trans_date = commUtilFun.addMouth(post_date_str,current_month-1,"sub")
                    installment.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(ins_trans_date + " 00:00:00"));
                    expense.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(ins_trans_date + " 00:00:00"));
                    installment.setBillId(UUID.randomUUID().toString());
                    installment.setTransferfeeDesc("");
                    installnum = installnum + 1;
                    if (installnum == 2) {
                        installments.add(installment);
                        installment = new Installment();
                        installnum = 0;
                    }
                }
            }
            billAllData.setInstallments(installments);
            logger.info("任务【{}】,已出账单【{}】月份，分期数据获取完成：{}", context.get(LUA_TASK_KEY), bill_mon, JSON.toJSONString(installments));
        } catch (e) {
            logger.info("任务【{}】，解析信用卡首页信息，卡【{}】,异常：{}", context.get(LUA_TASK_KEY), index, e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //抓取未出账单
    get_credit_undone_bill_html: function (index) {
        logger.info("任务【{}】，信用卡开始跳转到未出账单页面，抓取未出账单", context.get(LUA_TASK_KEY));
        var html = luaFuncs.get_credit_undone_bill_html(index);
        html = commUtilFun.get_html_with_retry(html, "未出账单查询");
        storeDataToFile(context, html, "credit_undone_bill_" + index + ".html");
        luaFuncs.saveHtmlAndImage("credit_undone_bill_" + index);
        context.put("cmb_credit_undone_bill_html", html);
        logger.info("任务【{}】，信用卡开始跳转到未出账单页面，抓取未出账单", context.get(LUA_TASK_KEY));
    },

    //解析未出账单信息
    parse_credit_undone_bill_html: function (creditCardAllData,bill_date) {
        try {
            logger.info("任务【{}】,开始解析信用卡未出账单信息", context.get(LUA_TASK_KEY));
            var html = context.get("cmb_credit_undone_bill_html");
            var doc = Jsoup.parse(html);
            //获取到未出账单的对象
            var billAllData = getUNDoneBillAllDataHeaderData(creditCardAllData);
            billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(bill_date));
            billAllData.setBillMonth(bill_date.substring(0, 7));
            billAllData.setCreditLimit(creditCardAllData.getCreditLimit());
            billAllData.setCashLimit(creditCardAllData.getCashLimit());
            billAllData.setUsdNewBalance(null);
            billAllData.setUsdMinPayment(null);
            billAllData.setUsdLastBalance(null);
            billAllData.setUsdLastPayment(null);
            billAllData.setUsdNewCharges(null);
            billAllData.setUsdInterest(null);
            billAllData.setInterest(null);
            billAllData.setUsdCreditLimit(null);
            billAllData.setUsdCashLimit(null);
            billAllData.setLastPayment(null);
            billAllData.setMinPayment(null);
            var unNewCharges = new BigDecimal(0);

            var expenseList = new ArrayList();
            //未记账部分
            //var unbilled = doc.getElementById("dgReckoningNotDetail_Unbilled").select("tr:not(:first-child)");
            //已记账部分
            var billed = doc.getElementById("dgReckoningNotDetail").select("tr:not(:first-child)");
            var bills = new Elements(billed);
            var index = 1;
            var unNewBalance = 0.0;
            //迭代
            for each(var tr in bills) {
                var expense = new Expense();

                var transDate = tr.select("td:first-child").text().trim(); // 交易日期
                //有尚未入账信息记账日期取交易日期 #dgReckoningNotDetail_Unbilled > tbody > tr:nth-child(2) > td:nth-child(2) > span

                var recordDate = equals("尚未入账",tr.select("td:nth-child(2)").text().trim())
                    ? tr.select("td:first-child").text().trim()
                    : tr.select("td:nth-child(2)").text().trim(); // 记账日期
                var remark = tr.select("td:nth-child(3)").text().trim(); // 交易摘要
                var transAdtr = tr.select("td:nth-child(4)").text().trim();// 交易地点
                var cardNo = tr.select("td:nth-child(5)").text().trim(); // 后四位
                var jyje = tr.select("td:nth-child(6)").text().trim(); // 交易金额
                unNewBalance =  unNewBalance + Double.parseDouble(stringToBigDecimal(jyje.replaceAll("￥", "")));
                expense.setId(UUID.randomUUID().toString());
                expense.setAmountMoney(stringToBigDecimal(jyje.replaceAll("￥", "")));
                expense.setCardNum(cardNo);
                if (expense.getAmountMoney().signum() == 1) {
                    unNewCharges = unNewCharges.add(expense.getAmountMoney());
                }
                expense.setOrderIndex(index++);
                expense.setTransDate(yyyy_MM_dd_PARSER.parse(transDate));
                expense.setCurrencyType("CNY");
                expense.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(transDate + " 00:00:00"));
                expense.setBalance(null);
                expense.setDescription(remark.replaceAll("&nbsp;", " ").replaceAll(" ", " "));
                expense.setTransAddr(transAdtr.replaceAll("&nbsp;", " ").replaceAll(" ", " "));
                expense.setPostDate(yyyy_MM_dd_PARSER.parse(recordDate));
                expense.setCategory(classify(remark,expense.getAmountMoney()));
                expense.setTransMethod("");
                expense.setTransChannel("");
                expense.setRemark("");
                expense.setOppositeCardNo("");
                expense.setNameOnOppositeCard("");
                expense.setOppositeBank("");
                expenseList.add(expense);
            }

            var lastNewBalance =  context.get("cmb_credit_un_last_balance");
            logger.info("任务号={},上期的账单金额:{}",context.get(LUA_TASK_KEY),lastNewBalance);
            if(lastNewBalance !==  null){
                unNewBalance = unNewBalance + Double.parseDouble(lastNewBalance);
                billAllData.setNewBalance(new BigDecimal(String.format("%.2f", unNewBalance)));
                billAllData.setLastBalance(new BigDecimal(lastNewBalance));
            }
            billAllData.setNewCharges(unNewCharges);
            billAllData.setShoppingSheets(expenseList);

            //未出账单分期数据解析
            logger.info("任务taskKey = {}，未出账账单详情：{}", context.get(LUA_TASK_KEY), JSON.toJSONString(expenseList));
            var installments = new ArrayList();
            var installment = new Installment();
            var installnum = 0;
            for each(var expense in expenseList) {
                var lists = getMatch("(账单分期)\\s*(.*?)\\s*(\\d{1,2}-\\d{1,2})", expense.getDescription());
                if (lists.size() == 1 && lists.get(0).size() == 3) {
                    var type = lists.get(0).get(1);
                    var installment_type = installmentTypeChange(type);
                    var dates = lists.get(0).get(2).split("-");
                    var total_month = Integer.parseInt(dates[1]);
                    var current_month = Integer.parseInt(dates[0]);
                    if (!expense.getDescription().contains("手续费")) {
                        installment.setAmountMoney(expense.getAmountMoney());
                        installment.setInstallmentDesc(expense.getDescription());
                    } else {
                        installment.setHandingFee(expense.getAmountMoney());
                        installment.setHandingfeeDesc(expense.getDescription());
                    }
                    installment.setCurrencyType("CNY");
                    installment.setTotalMonth(total_month);
                    installment.setCurrentMonth(current_month);
                    installment.setInstallmentType(installment_type);
                    installment.setTransferFee(null);
                    installment.setShoppingsheetId(UUID.randomUUID().toString());
                    installment.setPostDate(expense.getPostDate());
                    //根据记账时间计算出交易时间，并修改这个交易时间
                    var post_date_str = yyyy_MM_dd_FORMAT.format(expense.getPostDate())
                    var ins_trans_date = commUtilFun.addMouth(post_date_str,current_month-1,"sub")
                    installment.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(ins_trans_date + " 00:00:00"));
                    expense.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(ins_trans_date + " 00:00:00"));
                    installment.setBillId(UUID.randomUUID().toString());
                    installnum = installnum + 1;
                    if (installnum == 2) {
                        installments.add(installment);
                        installment = new Installment();
                        installnum = 0;
                    }
                }
            }
            logger.info("任务taskKey = {}，未出账账单分期明细：{}", context.get(LUA_TASK_KEY), JSON.toJSONString(installments));
            billAllData.setInstallments(installments);
            //处理未出账单的lastpayment
            var shopping_sheets = billAllData.getShoppingSheets();
            var last_payment = new BigDecimal(0.00);
            for(var i=0;i<shopping_sheets.size();i++){
                var expnese = shopping_sheets.get(i);
                if(expnese.getAmountMoney()!=null && expnese.getAmountMoney()<0){
                    last_payment = last_payment.add(expnese.getAmountMoney())
                }
            }
            if(!last_payment.equals(BigDecimal.ZERO)){
                billAllData.setLastPayment(last_payment);
            }
            logger.info("任务【{}】,解析信用卡未出账单信息完成", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.info("任务【{}】，解析信用卡未出账单信息完成,异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    get_undone_bill_date:function () {
        var bill_day = parseInt(context.get("cmb_bill_day"));
        var calendar = Calendar.getInstance();
        var now_day = parseInt(calendar.get(Calendar.DAY_OF_MONTH))
        var year = calendar.get(Calendar.YEAR);
        year = parseInt(year);
        var month = 0;
        if (now_day > bill_day) {
            month = calendar.get(Calendar.MONTH) + 2;// 获取当前月份
            month = Integer.parseInt(month);
        } else {
            month = calendar.get(Calendar.MONTH) + 1;
            month = Integer.parseInt(month);
        }
        var bill_date = year + "-" + (month < 10 ? "0" + month : month) + "-" + bill_day;
        return bill_date;
    }
}

/**
 * 通用方法集合
 **/
var commUtilFun = {
    /**
     * 注入js获取账户总览页面
     */
    get_card_list: function () {
        logger.info("任务【{}】,招商银行开始获取账户总览页面", context.get(LUA_TASK_KEY));
        var html = luaFuncs.get_card_list();
        html = commUtilFun.get_html_with_retry(html, "账户总览");
        storeDataToFile(context, html, "card_list.html");
        luaFuncs.saveHtmlAndImage("card_list");
        context.put("cmb_account_card_list", html);
    },

    /**
     * 解析卡列表信息，构建表头
     */
    parse_card_list_html: function () {
        try {
            logger.info("任务【{}】,解析卡列表信息开始", context.get(LUA_TASK_KEY));
            var html = context.get("cmb_account_card_list");
            var doc = Jsoup.parse(html);
            //获取借记卡和信用卡的卡数量
            var creditCardSize = 0;
            var debitCardSize = 0;
            var fieldset = doc.select("fieldset");
            if (fieldset != null && fieldset.size() > 0) {
                for (var i = 0; i < fieldset.size(); i++) {
                    if (fieldset.get(i).text().contains("活期结算户")) {
                        debitCardSize++;
                    } else if (fieldset.get(i).text().contains("信用卡账户")) {
                        creditCardSize++;
                    }
                }
            } else {
                logger.error("任务【{}】,未能获取到卡列表信息", context.get(LUA_TASK_KEY));
                throw new BankException("BALO-20304-30", "未能获取到卡列表信息");
            }
            context.put("cmb_debitCardSize", debitCardSize);
            context.put("cmb_creditCardSize", creditCardSize);
            logger.info("任务【{}】,解析卡列表信息完成,借记卡数量【{}】，信用卡数量【{}】", context.get(LUA_TASK_KEY), debitCardSize, creditCardSize);
        } catch (e) {
            logger.error("任务【{}】,解析卡列表信息异常：【{}】", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //重试获取页面方法
    get_html_with_retry: function (html, msg) {
        for (var i = 0; i < 3; i++) {
            if (html.contains(msg)) {
                logger.info("任务【{}】,招商获取" + msg + "页面成功", context.get(LUA_TASK_KEY));
                break;
            } else {
                logger.info("任务【{}】,招商获取" + msg + "页面失败，继续等待", context.get(LUA_TASK_KEY));
                Thread.sleep(5000)
                html = luaFuncs.get_login_index_html();
            }
        }
        if (!html.contains(msg)) {
            logger.info("任务【{}】,招商重试三次获取" + msg + "页面失败", context.get(LUA_TASK_KEY));
        }
        return html;
    },

    //获取指定月份之前的日期
    get_date_with_some_mon: function (format, mon) {
        var cld = Calendar.getInstance();
        var sdf = new SimpleDateFormat(format);
        cld.add(Calendar.MONTH, parseInt(mon));
        return sdf.format(cld.getTime());
    },

    /**
     * 获取两个月份中间的所有月份
     * @param start
     * @param end
     */
    get_mon_list: function (start, end) {
        var start_year = parseInt(start.substring(0, 4));
        var end_year = parseInt(end.substring(0, 4));
        var start_mon = parseInt(start.substring(5, 7));
        var end_mon = parseInt(end.substring(5, 7));
        var mon_list = new ArrayList();
        if (end_year < start_year) {
            //结束年小于开始年
            for (var i = start_mon; i >= 1; i--) {
                mon_list.add(start_year + "-" + (i < 10 ? "0" + i : i));
            }
            for (var i = 12; i >= end_mon; i--) {
                mon_list.add(end_year + "-" + (i < 10 ? "0" + i : i))
            }
        } else {
            //结束年小于开始年
            for (var i = start_mon; i >= end_mon; i--) {
                mon_list.add(start_year + "-" + (i < 10 ? "0" + i : i));
            }
        }
        logger.info("任务【{}】，获取到的月份列表【{}】", mon_list);
        return mon_list;
    },

    //判断是否存在该月账单,存在返回该月账单，不存在拿个新的返回
    is_exist_bill_with_mon: function (creditCardAllData, bill_mon) {
        var bills = creditCardAllData.getBills();
        for (var i = 0; i < bills.size(); i++) {
            var bill = bills.get(i);
            var billMonth = bill.getBillMonth()
            if (StringUtils.isNotBlank(billMonth) && billMonth.equals(bill_mon)) {
                return bill;
            }
        }
        return getDoneBillAllDataHeaderData(creditCardAllData);
    },

    get_debit_shopping_category: function (description) {
        var category = ""
        if (description.indexOf("消费") != -1) {
            category = "CONSUMPTION";
        } else if (description.indexOf("取款") != -1 || description.indexOf("现支") != -1) {
            category = "WITHDRAW";
        } else if (description.indexOf("存款") != -1 || description.indexOf("现存") != -1) {
            category = "DEPOSIT";
        } else if (description.indexOf("还款") != -1) {
            category = "REPAYMENT";
        } else if (description.indexOf("转账") != -1 || description.indexOf("汇入") != -1) {
            category = "TRANSFER";
        } else if (description.indexOf("结息") != -1 || description.indexOf("利息税") != -1) {
            category = "ACCRUAL";
        } else if (description.indexOf("手续费") != -1) {
            category = "HANDLINGFEE";
        } else if (description.indexOf("退货") != -1) {
            category = "REFUND";
        } else {
            category = "OTHERFEE";
        }
        return category

    },

    /**
     * 获取billdata中最大的orderIndex
     */
    get_bigest_order_index: function (billAllData) {
        var shoppingSheets = billAllData.getShoppingSheets();
        var installments = billAllData.getInstallments();

        var shop_order = 1;
        if (shoppingSheets.size() <= 0) {
            context.put("shopping_order", shop_order);
        } else {
            for (var i = 0; i < shoppingSheets.size(); i++) {
                var exp = shoppingSheets.get(i);
                var order_index = exp.getOrderIndex();
                if (parseInt(order_index) > parseInt(shop_order)) {
                    shop_order = parseInt(order_index);
                }
            }
            context.put("shopping_order", shop_order);
        }

        var in_order = 1;
        if (shoppingSheets.size() <= 0) {
            context.put("install_order", shop_order);
        } else {
            for (var i = 0; i < installments.size(); i++) {
                var ins = installments.get(i);
                var order_index = ins.getOrderIndex();
                if (parseInt(order_index) > parseInt(in_order)) {
                    in_order = parseInt(order_index);
                }
            }
            context.put("install_order", shop_order);
        }
    },

    /**
     * 处理billAllData
     */
    deal_debit_card_bill_all_data: function (billAllData, bill_mon) {
        billAllData.setBankName("招商银行");
        billAllData.setBillType("");
        billAllData.setBillId(UUID.randomUUID().toString());
        billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(bill_mon + "-01"));
        billAllData.setBillMonth(bill_mon);
        billAllData.setCashLimit(null);
        billAllData.setCreditLimit(null);
        billAllData.setInterest(null);
        billAllData.setLastBalance(null);
        billAllData.setLastPayment(null);
        billAllData.setMinPayment(null);
        billAllData.setNewBalance(null);
        billAllData.setNewCharges(null);
        billAllData.setUsdCashLimit(null);
        billAllData.setUsdCreditLimit(null);
        billAllData.setUsdInterest(null);
        billAllData.setUsdLastBalance(null);
        billAllData.setUsdLastPayment(null);
        billAllData.setUsdMinPayment(null);
        billAllData.setUsdNewBalance(null);
        billAllData.setUsdNewCharges(null);
    },

    //处理钱
    parse_money: function (str) {
        var jyje = str.replaceAll("￥", "");
        jyje = jyje.replaceAll(",", "");
        jyje = jyje.replaceAll(" ", "").trim();
        return jyje;
    },

    //处理字符串时间
    deal_str_date:function (datestr) {
        var new_date = "";
        if(datestr != null){
            new_date  = datestr.substring(0,4) +"-"+datestr.substring(4,6)+"-"+datestr.substring(6,8)
        }
        return new_date;
    },

    //计算分期的方法
    addMouth:function(date, num,type) {
        if(type == "add"){
            var mouthnum = parseInt(num);
            var year = parseInt(date.substring(0, 4));
            var mouth = parseInt(date.substring(5, 7));
            var day = parseInt(date.substring(8, 10));
            if (mouth + mouthnum > 12)
            {
                var newyear = year + 1;
                var newmouth = mouth + mouthnum - 12;
                var newday = day;
            }
            else
            {
                var newyear = year
                var newmouth = mouth + mouthnum;
                var newday = day;
            }
            var newdate = newyear + "-" + newmouth + "-" + newday;
            return newdate;
        }else{
            var mouthnum = parseInt(num);
            var year = parseInt(date.substring(0, 4));
            var mouth = parseInt(date.substring(5, 7));
            var day = parseInt(date.substring(8, 10));
            if (mouth - mouthnum < 0)
            {
                var num1 = Math.floor((mouthnum-mouth)/12)+1
                if(num1<=1){
                    var newyear = year - 1;
                    var newmouth = 0
                    if(mouth + mouthnum - 12 > 0){
                        newmouth = (mouth - mouthnum) + 12;
                    }else{
                        newmouth = 12 - (mouthnum-mouth);
                    }
                }else{
                    mouthnum = mouthnum % 12
                    var newyear = year - num1;
                    if(mouth - mouthnum <= 0){
                        var newmouth = 0
                        if(mouth + mouthnum - 12 > 0){
                            newmouth = (mouth - mouthnum) + 12;
                        }else{
                            newmouth = 12 - (mouthnum-mouth);
                        }
                    }else{
                        newmouth = mouth-mouthnum
                    }
                }
                var newday = day;
            }
            else
            {
                var newyear = year
                var newmouth = mouth - mouthnum;
                var newday = day;
            }
            var newdate = newyear + "-" + newmouth + "-" + newday;
            return newdate;
        }
    }
}

/**
 * lua方法集合
 */
var luaFuncs = {
    //=================================登录相关===============================================
    open: function () {
        var map = new LinkedHashMap();
        map.put("method", "open");
        return sendAndReceive(map)
    },
    checkControl: function () {
        var map = new LinkedHashMap();
        map.put("method", "checkControl");
        return sendAndReceive(map)
    },

    clickLoginButton: function (type) {
        var map = new LinkedHashMap();
        map.put("method", "clickLoginButton");
        map.put("type", type);
        return sendAndReceive(map)
    },
    sendMessage: function () {
        var map = new LinkedHashMap();
        map.put("method", "sendMessage");
        return sendAndReceive(map)
    },
    receiveMessage: function (smsMessage) {
        var map = new LinkedHashMap();
        map.put("method", "receiveMessage");
        map.put("smsMessage", smsMessage)
        return sendAndReceive(map)
    },
    checkMessage: function () {
        var map = new LinkedHashMap();
        map.put("method", "checkMessage");
        return sendAndReceive(map)
    },
    zs_check_img: function () {
        var map = new LinkedHashMap();
        map.put("method", "zs_check_img");
        return sendAndReceive(map)
    },
    input_username: function (cardNum) {
        var map = new LinkedHashMap();
        map.put("method", "input_username");
        map.put("cardNo", cardNum);
        return sendAndReceive(map)
    },

    input_password: function (passWord) {
        var map = new LinkedHashMap();
        map.put("method", "input_password");
        map.put("password", passWord);
        return sendAndReceive(map)
    },

    call_showPassWordLogin: function () {
        var map = new LinkedHashMap();
        map.put("method", "showPassWordLogin");
        return sendAndReceive(map)
    },
    saveHtmlAndImage: function (name) {
        var map = new HashMap();
        map.put("method", "saveHtmlAndImage");
        map.put("name", name);
        return sendAndReceive(map);
    },

    getCookie: function () {
        var map = new LinkedHashMap();
        map.put("method", "getCookie");
        return sendAndReceive(map)
    },

    //============================借记卡方法==================================
    /**
     * 获取登陆首页主frame信息
     */
    get_login_index_html: function () {
        //get_login_index_frame_html
        var map = new LinkedHashMap();
        map.put("method", "get_login_index_frame_html");
        return sendAndReceive(map)
    },

    /**
     * 获取卡列表
     */
    get_card_list: function () {
        var map = new LinkedHashMap();
        map.put("method", "get_card_list");
        return sendAndReceive(map)
    },
    /**
     * 点击去到一卡通开户信息页面
     */
    get_card_open_info: function () {
        var map = new LinkedHashMap();
        map.put("method", "get_card_open_info");
        return sendAndReceive(map)
    },

    /**
     * 跳转到存款页面，返回frame内容
     */
    get_debit_balance_html: function () {
        var map = new LinkedHashMap();
        map.put("method", "get_debit_balance_html");
        return sendAndReceive(map)
    },

    /**
     * 跳转到借记卡历史账单页面
     */
    get_debit_bill_index_html: function (card_num) {
        var map = new LinkedHashMap();
        map.put("method", "get_debit_bill_index_html");
        map.put("card_num", card_num);
        return sendAndReceive(map)
    },

    /**
     * 获取某子账户下的消费明细页面
     */
    get_debit_sub_account_shopping_html: function (start_date, end_date, index) {
        var map = new LinkedHashMap();
        map.put("method", "get_debit_sub_account_shopping_html");
        map.put("start_date", start_date);
        map.put("end_date", end_date);
        map.put("index", index);
        return sendAndReceive(map)
    },

    //=======================================信用卡方法===========================================
    click_into_credit_index: function () {
        var map = new LinkedHashMap();
        map.put("method", "click_into_credit_index");
        return sendAndReceive(map)
    },

    click_into_credit_open_index: function (index) {
        var map = new LinkedHashMap();
        map.put("method", "click_into_credit_open_index");
        map.put("card_index", index);
        return sendAndReceive(map)
    },

    click_into_credit_index_and_select_option: function (index) {
        var map = new LinkedHashMap();
        map.put("method", "click_into_credit_index_and_select_option");
        map.put("card_index", index);
        return sendAndReceive(map)
    },

    click_into_done_bill_index_and_select_option: function (index) {
        var map = new LinkedHashMap();
        map.put("method", "click_into_done_bill_index_and_select_option");
        map.put("card_index", index);
        return sendAndReceive(map)
    },

    get_credit_undone_bill_html: function (index) {
        var map = new LinkedHashMap();
        map.put("method", "get_credit_undone_bill_html");
        map.put("card_index", index);
        return sendAndReceive(map)
    }

}